#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2003,2004 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)09   1.9   src/csm/samples/sbin/sprc.perl, setup, csm_rameh, rameh0431a 6/17/04 01:12:17



#
#   Module:	Simple Platform-independent Resource Controller (SPRC)
#
#
#   Purpose:	The purpose of this script is to supply a simple platform independent
#              	interface to system daemons.  These are often refered to as resources.
#
#               sprc  provides users with an common command line interface that can handle
#               typical resource managment tasks on both AIX and Linux cluser nodes.
#
#               When used with CFM, sprc simplifies managing daemons across a hetrogenous
#		cluster.
#
#
#  Source:	/opt/csm/samples/sbin/sprc.perl 
#
#  Installed:	/opt/csm/bin/sprc
#
#
#
#  Exceptions:	This tool supports exceptions to the variety of names found with known
#		resources.  sprc has the reponsibility for resolving the name correctly
#		for a given platform ( see aixExceptionHandler for example- and yes it is
#		a hack )
#
#		If you add an exception to this tool,  please update the list.
#
#		.  autofs	= automountd
#		.  ntpd		= xntpd
#



#--------------------------------------------------------------------------------

=head1    sprc.perl

        Development notes:

        The html view of the pod headers in this file can be updated
        by running the command:

                  pod sprc.perl

        The html veiw of the pod headers will be in the file sprc.perl.html

=cut

#--------------------------------------------------------------------------------

=head3	use staements


=cut

#--------------------------------------------------------------------------------

use strict;
#use lib $::csmpm;
use FindBin qw($Bin);
use lib "$Bin";
use Getopt::Long;


#--------------------------------------------------------------------------------

=head3  file scope data

=cut

#--------------------------------------------------------------------------------

# remote shell vairables
my $aix_rsh;  
my $linux_ssh;

my $AIX_AUTOFS_CMD = "/usr/sbin/automount";
    

#--------------------------------------------------------------------------------

=head3  messages

=cut

#--------------------------------------------------------------------------------

my $EMsgAIXOnly = "the -g flag is only appropriate for AIX hosts. \n";
my $EMsgNoResource = "sprc:  need a  resource for this command - try:  sprc --help \n";
my $EMsgUnsupporteOS =  "sprc:  unsupported Operating System \n";
my $IMsgNoParameters =  "sprc:  parmeters needed for this command - try:  sprc --help\n";
my $IMsgUsage  = "Usage: sprc [[-h?vV]|{[--cycle|-c]|[--kill|-k]|[--list|-l]|[--start|-s]|[--stop]}][[--remote|-r]{name|ipaddr}]{res|-g group}\n";


#--------------------------------------------------------------------------------

=head3  sub usage

=cut

#--------------------------------------------------------------------------------

sub usage () {
    print $IMsgUsage;
    exit;
}


#--------------------------------------------------------------------------------

=head3  sub help

=cut

#--------------------------------------------------------------------------------

sub help() {

    print "\n";
    print "--------------------------------------------------------------------------------\n";
    print "\n";
    print "sprc:   simple platform independent resource controller\n";

    print "\n";
    print $IMsgUsage;
    print "\n";

    print "Options: \n";
    print "    -c | --cycle         - kill and restart a running resource.\n";
    print "    -g                   - apply operation to a resource group (AIX only)\n";
    print "    -h | ?               - print short usage message. \n";
    print "    --help               - print this help message. \n";
    print "    -k | --kill          - stop a resource (same as --stop). \n";
    print "    -l | --list          - list the status of a resource. \n";
    print "    -r | --remote        - execute operation on a remote host.\n";
    print "    -s | --start         - start a resource. \n";
    print "    --stop               - stop a resource (same as -k,--kill). \n";
    print "    -v | -V              - verbose output. \n";

    print "\n";
    print "Examples: \n";

    print "\n";
    print "    Kill and start a running instance of ntpd on the local host. \n";

    print "\n";
    print "        sprc -c ntpd \n";
   
    print "\n";
    print "    Kill and start ntpd on the remote host, validHostName. \n";

    print "\n";
    print "        sprc --cycle --remote validHostName ntpd \n";

    print "\n";


    exit;
}


#--------------------------------------------------------------------------------

=head3  sub getArgs

=cut

#--------------------------------------------------------------------------------

sub getArgs
{
    # Checks case in GetOptions
    $Getopt::Long::ignorecase = 0;

    # Allows opts to be grouped (e.g. -avx)
    Getopt::Long::Configure("bundling");

    if ( !@ARGV ) { print $IMsgNoParameters; exit; }
    GetOptions(
                    'c'           => \$::CYCLE,
                    'cycle'       => \$::CYCLE,
                    'h|?'         => \$::USAGE,
                    'g'           => \$::GROUP,
                    'group'       => \$::GROUP,
                    'help'        => \$::HELP,
                    'k'           => \$::KILL,
                    'kill'        => \$::KILL,
                    'l'           => \$::LIST,
                    'list'        => \$::LIST,
                    'r'           => \$::RHOST,
                    'remote'      => \$::RHOST,
                    's'           => \$::START,
                    'start'       => \$::START,
                    'stop'        => \$::KILL,
                    'v'           => \$::VERBOSE,
                    'V'           => \$::VERBOSE,
    );

    if ( $::USAGE )   { print $IMsgUsage; }
    if ( $::HELP )    { &help(); }
    if ( $::RHOST )   { $aix_rsh   = " rsh "; $linux_ssh = " ssh "; }
}


#--------------------------------------------------------------------------------

=head3  sub getPlatform

	Returns a testable OS Platform string.

=cut

#--------------------------------------------------------------------------------

sub getPlatform
{

    my $platform =  qx ' uname -s ';
    chomp ( $platform );


    if ( $platform eq "AIX" )
        { return "AIX"; }

    elsif ($platform eq "Linux")
    {
        if (-f "/etc/redhat-release") { return "Redhat"; }

        elsif ( -f "/etc/SuSE-release" )
        {       
            if ( !system( "grep SLES-7 /etc/SuSE-release " ) )
            {
                 return "SLES-7";
            }
            elsif ( !system( "grep SLES- /etc/SuSE-release " ) || !system( "grep -i 'SuSE Linux' /etc/SuSE-release")) 
            {
                 return "Not_SLES-7";  # SLES but not SLES-7
            }
        }
    }
    else # error, unsupported platform
    {  
        print " $EMsgUnsupporteOS \n";
        exit;
    }
}

#--------------------------------------------------------------------------------

=head3  sub aixExceptionHandler - put special daemon-specific hacks here

=cut

#--------------------------------------------------------------------------------

sub aixExceptionHandler 
{

    my ( $resource ) = @_;

    # switch on $resource

    if ( $resource eq "autofs" )
    {
        if ( $::GROUP ) { return "autofs"; }

        return "automountd";
     }

    if ( $resource eq "automount" )
    {
        if ( $::GROUP ) { return "autofs"; }

        return "automountd";
    }

    if ( $resource eq "automountd" )
    {
        if ( $::GROUP ) { return "autofs"; }

        return "automountd";
    }

    if ( $resource eq "ntpd" )   { return "xntpd"; }

    return $resource;

}


#--------------------------------------------------------------------------------

=head3  sub redhatExceptionHandler - put special daemon-specific hack here.

=cut

#--------------------------------------------------------------------------------

sub redhatExceptionHandler 
{

    my ( $resource ) = @_;

    # switch on $resource

    if ( $resource eq "automountd" ) { return "autofs"; }

    if ( $resource eq "xntpd" )      { return "ntpd"; }

    return $resource;

}


#--------------------------------------------------------------------------------

=head3  sub sles7ExceptionHandler - put special daemon-specific hacks here

=cut

#--------------------------------------------------------------------------------

sub sles7ExceptionHandler
{

    my ( $resource )   = @_;

    # switch on $resource

    if ( $resource eq "automountd" ) { return "autofs"; }

    if ( $resource eq "ntpd" )       { return "xntpd"; }

    return $resource;

}


#--------------------------------------------------------------------------------

=head3  sub notSles7ExceptionHandler - put special daemon-specific hacks here

=cut

#--------------------------------------------------------------------------------

sub notSles7ExceptionHandler 
{

    my ( $resource ) = @_;

    # switch on $resource

    if ( $resource eq "automountd" ) { return "autofs"; }

    if ( $resource eq "ntpd" )       { return "xntpd"; }

    return $resource;

}


#--------------------------------------------------------------------------------

=head3  sub aixRsourceHandler

        Handles AIX Unix resource requirements

        Notes:

=cut

#--------------------------------------------------------------------------------

sub aixResourceHandler
{
    my $scope;
    my ( $resource, $host )   = @_;

    # $scope is either -s or -g
    if   ( $::GROUP ) { $scope = " -g "; }
    else              { $scope = " -s "; }

    if ( $::CYCLE)
    {
        # recycle the daemon
        system ( "$aix_rsh $host stopsrc  $scope $resource " );
        system ( "$aix_rsh $host startsrc $scope $resource " );

        # start the autofs subsystem
        system ( $AIX_AUTOFS_CMD );
    }
    if ( $::KILL )
    {
        system ( "$aix_rsh $host stopsrc $scope $resource " );
    }
    if ( $::LIST)
    {
        system ( "$aix_rsh $host lssrc $scope $resource " );
    }
    if ( $::START)
    {
        # start the daemon
        system ( "$aix_rsh $host startsrc $scope $resource " );

        # start the autofs subsystem
        system ( $AIX_AUTOFS_CMD );
    }
}

#--------------------------------------------------------------------------------

=head3  sub redhatResourceHandler

        Handles Redhat Linux resource requirements

        Notes:

=cut

#--------------------------------------------------------------------------------

sub redhatResourceHandler
{
    my ( $resource, $host )   = @_;

    #  set absolute path to linux resource ( in init.d )
    my $abs_resource = "/etc/init.d/$resource";

    if ( $::CYCLE)
    {
        system ( "$linux_ssh $host  $abs_resource stop " );
        system ( "$linux_ssh $host $abs_resource start " );
    }
    if ( $::KILL )
    {
        system ( "$linux_ssh $host $abs_resource stop " );
    }
    if ( $::LIST)
    {
        system ( "$linux_ssh $host $abs_resource status " );
    }
    if ( $::START)
    {
        system ( "$linux_ssh $host $abs_resource start " );
    }
}

#--------------------------------------------------------------------------------

=head3  sub sles7ResourceHandler

        Handles SuSE 7 Linux resource requirements

        Notes:

=cut

#--------------------------------------------------------------------------------

sub sles7ResourceHandler
{

    my ( $resource, $host )   = @_;

    #  set absolute path to linux resource ( in init.d )
    my $abs_resource = "/etc/init.d/$resource";

    if ( $::CYCLE)
    {
        system ( "$linux_ssh $host  $abs_resource stop " );
        system ( "$linux_ssh $host $abs_resource start " );
    }
    if ( $::KILL )
    {
        system ( "$linux_ssh $host $abs_resource stop " );
    }
    if ( $::LIST)
    {
        system ( "$linux_ssh $host $abs_resource status " );
    }
    if ( $::START)
    {
        system ( "$linux_ssh $host $abs_resource start " );
    }
}

#--------------------------------------------------------------------------------

=head3  sub notSles7ResourceHandler

        Handles SuSE 8 Linux resource requirements

        Notes:

=cut

#--------------------------------------------------------------------------------

sub notSles7ResourceHandler
{

    my ( $resource, $host )   = @_;

    #  set absolute path to linux resource ( in init.d )
    my $abs_resource = "/etc/init.d/$resource";

    if ( $::CYCLE)
    {
        system ( "$linux_ssh $host  $abs_resource stop " );
        system ( "$linux_ssh $host $abs_resource start " );
    }
    if ( $::KILL )
    {
        system ( "$linux_ssh $host $abs_resource stop " );
    }
    if ( $::LIST)
    {
        system ( "$linux_ssh $host $abs_resource status " );
    }
    if ( $::START)
    {
        system ( "$linux_ssh $host $abs_resource start " );
    }
}


#--------------------------------------------------------------------------------

=head3  Main MAIN main

	process comand line then switch on $platform.

=cut

#--------------------------------------------------------------------------------

{ #  main block - controls scope of data

    # values from cmd line
    my $resource;
    my $host;
    
    # get arguments
    &getArgs();
    
    # get $platform
    my $platform = &getPlatform();
    if ( $platform == -1 ) { exit; }
    
    # get the hostname if remote shell flag is set
    if ( $::RHOST ) { $host = shift @::ARGV; }
    
    # get resource
    if ( @::ARGV )
        { $resource = shift @::ARGV; }
    else
        { print $EMsgNoResource; }
    
    #  handle AIX only condition
    if ( $::GROUP && $platform != "AIX" ) { print $EMsgAIXOnly; exit; }
    
    # switch on $platform
    {  
        if ( $platform eq "AIX" )
        { 
            $resource = &aixExceptionHandler ( $resource );
            &aixResourceHandler( $resource, $host );
        }
        elsif ( $platform eq "Redhat" )
        {
            $resource = &redhatExceptionHandler ( $resource );
            &redhatResourceHandler( $resource );
        }
        elsif ( $platform eq "SLES-7" )
        {
            $resource = &sles7ExceptionHandler ( $resource );
            &sles7ResourceHandler( $resource );
        }
        elsif ( $platform eq "Not_SLES-7" )
        {
            $resource = &notSles7ExceptionHandler ( $resource );
            &notSles7ResourceHandler( $resource );
        }
    }
}
